package model;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ConnectException;
import java.net.Socket;
import java.net.UnknownHostException;

/**
 *
 * @author Dustin & Maik
 */
public class Client extends Thread implements SMTP {

    /**
     * The default port to use for connections.
     */
    public final static int DEFAULT_PORT = 587;
    private boolean connected;
    private BufferedReader bufIn;
    private BufferedWriter bufOut;
    private Socket socket;
    private MessageOutput output;

    public Client(MessageOutput aMessageOutput) {
        output = aMessageOutput;
    }

    /**
     * Command wait for incoming messages.
     */
    @Override
    public void run() {
        while(connected) {
            try {
                String readLine;
                while((readLine = bufIn.readLine()) != null && !readLine.equals(DISCONNECT)) {
                    output.addMessage("S: " + readLine);
                }
            } catch(IOException ex) {
                ex.printStackTrace();
            } finally {
                disconnect();
            }
        }
    }

    public boolean isConnected() {
        return connected;
    }

    /**
     * Command to connect to a given host oon the default port.
     * @param host The host to connect to
     */
    public void connect(String host) {
        if(!connected) {
            try {
                socket = new Socket(host, DEFAULT_PORT);
                bufIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                bufOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                connected = true;
                output.addMessage("Connected to " + host);
            } catch(ConnectException ex) {
                ex.printStackTrace();
            } catch(UnknownHostException ex) {
                ex.printStackTrace();
            } catch(IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    /**
     * Command to close the Socket, BufferedReader and BufferedWriter thus
     * closing al communication,
     */
    public void disconnect() {
        if(connected) {
            try {
                connected = false;
                socket.close();
                bufIn.close();
                bufOut.close();
                output.addMessage("Disconnected");
            } catch(IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    /**
     * Command to write the given String out.
     * @param message the String to be written out
     */
    public void sendMessage(String message) {
        if(connected) {
            try {
                bufOut.write(message + CRLF);
                bufOut.flush();
            } catch(IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}
